home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Prefs / exec.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  25KB  |  709 lines

  1. /*
  2.  * exec.c  V3.1
  3.  *
  4.  * TM Exec object class
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Local data */
  19. #define PROPCHUNKS 8
  20. static const ULONG PropChunkTable[2 * PROPCHUNKS] = {
  21.  ID_TMEX, ID_CDIR,
  22.  ID_TMEX, ID_CMND,
  23.  ID_TMEX, ID_DATA,
  24.  ID_TMEX, ID_HKEY,
  25.  ID_TMEX, ID_NAME,
  26.  ID_TMEX, ID_OUTP,
  27.  ID_TMEX, ID_PATH,
  28.  ID_TMEX, ID_PSCR
  29. };
  30. static const char *TextTitle;
  31. static const char *HelpCommand;
  32. static const char *HelpHotKey;
  33. static const char *TextExecType;
  34. static const char *HelpExecType;
  35. static const char *TextExecTypes[TMET_Network - TMET_CLI + 2];
  36. static const char *TextStack;
  37. static const char *HelpStack;
  38. static const char *TextPriority;
  39. static const char *HelpPriority;
  40. static const char *HelpDirectory;
  41. static const char *TextPath;
  42. static const char *HelpPath;
  43. static const char *TextOutput;
  44. static const char *HelpOutput;
  45. static const char *HelpPublicScreen;
  46. static const char *TextArguments;
  47. static const char *HelpArguments;
  48. static const char *TextToFront;
  49. static const char *HelpToFront;
  50.  
  51. /* For which exec type is which data valid? */
  52. #define VALIDF_POPBUTTON 0x01
  53. #define VALIDF_STACK     0x02
  54. #define VALIDF_PRIORITY  0x04
  55. #define VALIDF_ARGUMENTS 0x08
  56. #define VALIDF_DIRECTORY 0x10
  57. #define VALIDF_PATH      0x20
  58. #define VALIDF_OUTPUT    0x40
  59. static const ULONG NotValidMasks[TMET_Network - TMET_CLI + 1] = {
  60.  /* CLI */     ~(VALIDF_POPBUTTON | VALIDF_STACK     | VALIDF_PRIORITY |
  61.                  VALIDF_ARGUMENTS | VALIDF_DIRECTORY | VALIDF_PATH     |
  62.                  VALIDF_OUTPUT),
  63.  /* WB */      ~(VALIDF_POPBUTTON | VALIDF_STACK     | VALIDF_PRIORITY |
  64.                  VALIDF_ARGUMENTS | VALIDF_DIRECTORY | 0               |
  65.                  0),
  66.  /* ARexx */   ~(VALIDF_POPBUTTON | 0                | 0               |
  67.                  VALIDF_ARGUMENTS | VALIDF_DIRECTORY | 0               |
  68.                  0),
  69.  /* Dock */    ~(0                | 0                | 0               |
  70.                  0                | 0                | 0               |
  71.                  0),
  72.  /* HotKey */  ~(0                | 0                | 0               |
  73.                  0                | 0                | 0               |
  74.                  0),
  75.  /* Network */ ~(0                | 0                | 0               |
  76.                  0                | 0                | 0               |
  77.                  0)
  78. };
  79.  
  80. /* Exec class instance data */
  81. struct ExecClassData {
  82.  ULONG       ecd_Flags;
  83.  ULONG       ecd_ExecType;
  84.  ULONG       ecd_Stack;
  85.  LONG        ecd_Priority;
  86.  const char *ecd_Command;
  87.  const char *ecd_HotKey;
  88.  const char *ecd_Directory;
  89.  const char *ecd_Path;
  90.  const char *ecd_Output;
  91.  const char *ecd_PubScreen;
  92.  Object     *ecd_Active;
  93.  Object     *ecd_TypeCycle;
  94.  Object     *ecd_CmdString;
  95.  Object     *ecd_HotKeyString;
  96.  Object     *ecd_StackInteger;
  97.  Object     *ecd_PriorityNumeric;
  98.  Object     *ecd_DirString;
  99.  Object     *ecd_PathString;
  100.  Object     *ecd_OutputString;
  101.  Object     *ecd_PubScreenString;
  102.  Object     *ecd_Arguments;
  103.  Object     *ecd_ToFront;
  104. };
  105. #define TYPED_INST_DATA(cl, o) ((struct ExecClassData *) INST_DATA((cl), (o)))
  106.  
  107. /* Exec class method: OM_NEW */
  108. #undef  DEBUGFUNCTION
  109. #define DEBUGFUNCTION ExecClassNew
  110. static ULONG ExecClassNew(Class *cl, Object *obj, struct opSet *ops)
  111. {
  112.  EXEC_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  113.            PrintTagList(ops->ops_AttrList)))
  114.  
  115.  /* Create object */
  116.  if (obj = (Object *) DoSuperNew(cl, obj,
  117.                                        MUIA_Window_Title, TextTitle,
  118.                                        MUIA_HelpNode,     "ExecWindow",
  119.                                        TMA_Type,          TMOBJTYPE_EXEC,
  120.                                        TAG_MORE,          ops->ops_AttrList)) {
  121.   struct ExecClassData *ecd = TYPED_INST_DATA(cl, obj);
  122.  
  123.   /* Initialize instance data */
  124.   ecd->ecd_Flags     = DATA_EXECF_ARGUMENTS;
  125.   ecd->ecd_ExecType  = TMET_CLI;
  126.   ecd->ecd_Stack     = 4096;
  127.   ecd->ecd_Priority  = 0;
  128.   ecd->ecd_Command   = NULL;
  129.   ecd->ecd_HotKey    = NULL;
  130.   ecd->ecd_Directory = NULL;
  131.   ecd->ecd_Path      = NULL;
  132.   ecd->ecd_Output    = NULL;
  133.   ecd->ecd_PubScreen = NULL;
  134.   ecd->ecd_Active    = NULL;
  135.  }
  136.  
  137.  EXEC_LOG(LOG1(Result, "0x%08lx", obj))
  138.  
  139.  /* Return pointer to created object */
  140.  return((ULONG) obj);
  141. }
  142.  
  143. /* Exec class method: OM_DISPOSE */
  144. #undef  DEBUGFUNCTION
  145. #define DEBUGFUNCTION ExecClassDispose
  146. static ULONG ExecClassDispose(Class *cl, Object *obj, Msg msg)
  147. {
  148.  struct ExecClassData *ecd = TYPED_INST_DATA(cl, obj);
  149.  
  150.  EXEC_LOG(LOG1(Disposing, "0x%08lx", obj))
  151.  
  152.  /* Free instance data */
  153.  if (ecd->ecd_Command)   FreeVector(ecd->ecd_Command);
  154.  if (ecd->ecd_HotKey)    FreeVector(ecd->ecd_HotKey);
  155.  if (ecd->ecd_Directory) FreeVector(ecd->ecd_Directory);
  156.  if (ecd->ecd_Path)      FreeVector(ecd->ecd_Path);
  157.  if (ecd->ecd_Output)    FreeVector(ecd->ecd_Output);
  158.  if (ecd->ecd_PubScreen) FreeVector(ecd->ecd_PubScreen);
  159.  
  160.  /* Call SuperClass */
  161.  return(DoSuperMethodA(cl, obj, msg));
  162. }
  163.  
  164. /* Exec class method: TMM_Finish */
  165. #undef  DEBUGFUNCTION
  166. #define DEBUGFUNCTION ExecClassFinish
  167. static ULONG ExecClassFinish(Class *cl, Object *obj, struct TMP_Finish *tmpf)
  168. {
  169.  struct ExecClassData *ecd = TYPED_INST_DATA(cl, obj);
  170.  
  171.  EXEC_LOG(LOG1(Type, "%ld", tmpf->tmpf_Type))
  172.  
  173.  /* MUI objects allocated? */
  174.  if (ecd->ecd_Active) {
  175.  
  176.   /* Use or Cancel? */
  177.   if (tmpf->tmpf_Type == TMV_Finish_Use) {
  178.  
  179.    /* Get new exec type */
  180.    GetAttr(MUIA_Cycle_Active, ecd->ecd_TypeCycle, &ecd->ecd_ExecType);
  181.  
  182.    /* Get new string contents */
  183.    ecd->ecd_Command   = GetStringContents(ecd->ecd_CmdString,
  184.                                           ecd->ecd_Command);
  185.    ecd->ecd_HotKey    = GetStringContents(ecd->ecd_HotKeyString,
  186.                                           ecd->ecd_HotKey);
  187.    ecd->ecd_Directory = GetStringContents(ecd->ecd_DirString,
  188.                                           ecd->ecd_Directory);
  189.    ecd->ecd_Path      = GetStringContents(ecd->ecd_PathString,
  190.                                           ecd->ecd_Path);
  191.    ecd->ecd_Output    = GetStringContents(ecd->ecd_OutputString,
  192.                                           ecd->ecd_Output);
  193.    ecd->ecd_PubScreen = GetStringContents(ecd->ecd_PubScreenString,
  194.                                           ecd->ecd_PubScreen);
  195.  
  196.    /* Get new numeric values */
  197.    GetAttr(MUIA_String_Integer, ecd->ecd_StackInteger,    &ecd->ecd_Stack);
  198.    GetAttr(MUIA_Numeric_Value,  ecd->ecd_PriorityNumeric, &ecd->ecd_Priority);
  199.  
  200.    /* Get new flag states */
  201.    ecd->ecd_Flags = GetCheckmarkState(ecd->ecd_Arguments,
  202.                                       DATA_EXECF_ARGUMENTS) |
  203.                     GetCheckmarkState(ecd->ecd_ToFront,
  204.                                       DATA_EXECF_TOFRONT);
  205.   }
  206.  
  207.   /* Reset pointer to file name area */
  208.   ecd->ecd_Active = NULL;
  209.  }
  210.  
  211.  /* Call SuperClass */
  212.  return(DoSuperMethodA(cl, obj, (Msg) tmpf));
  213. }
  214.  
  215. /* Exec class method: TMM_Edit */
  216. #undef  DEBUGFUNCTION
  217. #define DEBUGFUNCTION ExecClassEdit
  218. static ULONG ExecClassEdit(Class *cl, Object *obj, struct TMP_Edit *tmpe)
  219. {
  220.  struct ExecClassData *ecd = TYPED_INST_DATA(cl, obj);
  221.  
  222.  /* MUI objects allocated? */
  223.  if (ecd->ecd_Active) {
  224.  
  225.   EXEC_LOG(LOG0(Object already active))
  226.  
  227.   /* Yes, forward method to SuperClass */
  228.   DoSuperMethodA(cl, obj, (Msg) tmpe);
  229.  
  230.  /* No, create object edit area */
  231.  } else if (ecd->ecd_Active =
  232.     VGroup,
  233.      Child, ColGroup(2),
  234.       Child, Label2(TextExecType),
  235.       Child, ecd->ecd_TypeCycle    = CycleObject,
  236.        MUIA_Cycle_Entries, TextExecTypes,
  237.        MUIA_Cycle_Active,  ecd->ecd_ExecType,
  238.        MUIA_CycleChain,    TRUE,
  239.        MUIA_ShortHelp,     HelpExecType,
  240.       End,
  241.       Child, Label2(TextGlobalCommand),
  242.       Child, ecd->ecd_CmdString    = TMPopFile(TextGlobalSelectCmd,
  243.                                                ecd->ecd_Command,
  244.                                                LENGTH_FILENAME, HelpCommand),
  245.       End,
  246.       Child, Label2(TextGlobalHotKey),
  247.       Child, ecd->ecd_HotKeyString = TMPopHotKey(ecd->ecd_HotKey, HelpHotKey),
  248.       End,
  249.       Child, Label2(TextStack),
  250.       Child, ecd->ecd_StackInteger = TMInteger(ecd->ecd_Stack, HelpStack),
  251.      End,
  252.      Child, HGroup,
  253.       Child, Label1(TextPriority),
  254.       Child, ecd->ecd_PriorityNumeric = NumericbuttonObject,
  255.        MUIA_Numeric_Min,   -128,
  256.        MUIA_Numeric_Max,   127,
  257.        MUIA_Numeric_Value, ecd->ecd_Priority,
  258.        MUIA_CycleChain,    TRUE,
  259.        MUIA_ShortHelp,     HelpPriority,
  260.       End,
  261.       Child, HSpace(0),
  262.       Child, Label1(TextArguments),
  263.       Child, ecd->ecd_Arguments =
  264.        MakeCheckmark(ecd->ecd_Flags & DATA_EXECF_ARGUMENTS, HelpArguments),
  265.       Child, HSpace(0),
  266.       Child, Label1(TextToFront),
  267.       Child, ecd->ecd_ToFront   =
  268.        MakeCheckmark(ecd->ecd_Flags & DATA_EXECF_TOFRONT, HelpToFront),
  269.      End,
  270.      Child, ColGroup(2),
  271.       Child, Label2(TextGlobalDirectory),
  272.       Child, ecd->ecd_DirString       = TMPopFile(TextGlobalSelectDir,
  273.                                                   ecd->ecd_Directory,
  274.                                                   LENGTH_FILENAME,
  275.                                                   HelpDirectory),
  276.        ASLFR_DrawersOnly, TRUE,
  277.       End,
  278.       Child, Label2(TextPath),
  279.       Child, ecd->ecd_PathString      = TMString(ecd->ecd_Path,
  280.                                                  LENGTH_PATH, HelpPath),
  281.       Child, Label2(TextOutput),
  282.       Child, ecd->ecd_OutputString    = TMPopFile(TextGlobalSelectFile,
  283.                                                   ecd->ecd_Output,
  284.                                                   LENGTH_FILENAME, HelpOutput),
  285.       End,
  286.       Child, Label2(TextGlobalPublicScreen),
  287.       Child, ecd->ecd_PubScreenString = TMPopScreen(ecd->ecd_PubScreen,
  288.                                                     HelpPublicScreen),
  289.       End,
  290.      End,
  291.     End) {
  292.  
  293.   EXEC_LOG(LOG1(Exec Area, "0x%08lx", ecd->ecd_Active))
  294.  
  295.   /* Gadget actions */
  296.   DoMethod(ecd->ecd_TypeCycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
  297.            obj, 1, TMM_Change);
  298.   DoMethod(ecd->ecd_ToFront,   MUIM_Notify, MUIA_Selected,     MUIV_EveryTime,
  299.            obj, 1, TMM_Change);
  300.  
  301.   /* Set initial disable states */
  302.   DoMethod(obj, TMM_Change);
  303.  
  304.   /* Forward method to SuperClass */
  305.   if (DoSuperMethod(cl, obj, TMM_Edit, ecd->ecd_Active) == NULL) {
  306.  
  307.    /* SuperClass failed, delete file area again */
  308.    MUI_DisposeObject(ecd->ecd_Active);
  309.    ecd->ecd_Active = NULL;
  310.   }
  311.  }
  312.  
  313.  EXEC_LOG(LOG1(Result, "0x%08lx", ecd->ecd_Active))
  314.  
  315.  /* Return pointer to file area object to indicate success */
  316.  return((ULONG) ecd->ecd_Active);
  317. }
  318.  
  319. /* Exec class method: TMM_Change */
  320. #undef  DEBUGFUNCTION
  321. #define DEBUGFUNCTION ExecClassChange
  322. static ULONG ExecClassChange(Class *cl, Object *obj)
  323. {
  324.  struct ExecClassData *ecd = TYPED_INST_DATA(cl, obj);
  325.  
  326.  EXEC_LOG(LOG0(Entry))
  327.  
  328.  /* Check exec type */
  329.  {
  330.   ULONG mask;
  331.   ULONG state;
  332.  
  333.   /* Get state of type cycle gadget */
  334.   GetAttr(MUIA_Cycle_Active, ecd->ecd_TypeCycle, &state);
  335.  
  336.   /* Get valid mask for exec type */
  337.   mask = NotValidMasks[state];
  338.  
  339.   /* Set disabled states according to mask */
  340.   SetAttrs(ecd->ecd_CmdString, TMA_ButtonDisabled, mask & VALIDF_POPBUTTON,
  341.                                TAG_DONE);
  342.   SetDisabledState(ecd->ecd_StackInteger,    mask & VALIDF_STACK);
  343.   SetDisabledState(ecd->ecd_PriorityNumeric, mask & VALIDF_PRIORITY);
  344.   SetDisabledState(ecd->ecd_Arguments,       mask & VALIDF_ARGUMENTS);
  345.   SetDisabledState(ecd->ecd_DirString,       mask & VALIDF_DIRECTORY);
  346.   SetDisabledState(ecd->ecd_PathString,      mask & VALIDF_PATH);
  347.   SetDisabledState(ecd->ecd_OutputString,    mask & VALIDF_OUTPUT);
  348.  }
  349.  
  350.  /* Public screen gadget is enabled when "To Front" is selected */
  351.  SetDisabledState(ecd->ecd_PubScreenString,
  352.                   !GetCheckmarkState(ecd->ecd_ToFront, TRUE));
  353.  
  354.  /* Return 1 to indicate that the method is implemented */
  355.  return(1);
  356. }
  357.  
  358. /* Exec class method: TMM_ParseIFF */
  359. #undef  DEBUGFUNCTION
  360. #define DEBUGFUNCTION ExecClassParseIFF
  361. static ULONG ExecClassParseIFF(Class *cl, Object *obj,
  362.                                struct TMP_ParseIFF *tmppi)
  363. {
  364.  BOOL rc = FALSE;
  365.  
  366.  EXEC_LOG(LOG1(Handle, "0x%08lx", tmppi->tmppi_IFFHandle))
  367.  
  368.  /* Initialize IFF parser */
  369.  if ((PropChunks(tmppi->tmppi_IFFHandle, PropChunkTable, PROPCHUNKS) == 0) &&
  370.      (StopOnExit(tmppi->tmppi_IFFHandle, ID_TMEX, ID_FORM) == 0) &&
  371.      (ParseIFF(tmppi->tmppi_IFFHandle, IFFPARSE_SCAN) == IFFERR_EOC)) {
  372.   struct StoredProperty *spname;
  373.  
  374.   EXEC_LOG(LOG0(FORM TMEX chunk parsed OK))
  375.  
  376.   /* Check for mandatory NAME property */
  377.   if (spname = FindProp(tmppi->tmppi_IFFHandle, ID_TMEX, ID_NAME)) {
  378.    struct StoredProperty *spdata;
  379.  
  380.    EXEC_LOG(LOG2(Name, "%s (0x%08lx)", spname->sp_Data, spname->sp_Data))
  381.  
  382.    /* Check for mandatory DATA property */
  383.    if (spdata = FindProp(tmppi->tmppi_IFFHandle, ID_TMEX, ID_DATA)) {
  384.     struct ExecClassData *ecd = TYPED_INST_DATA(cl, obj);
  385.     struct ExecDATAChunk *edc = spdata->sp_Data;
  386.  
  387.     EXEC_LOG(LOG5(Data, "ID 0x%08lx Flags 0x%08lx Type %ld Prio %ld Stack %ld",
  388.                         edc->edc_Standard.sdc_ID, edc->edc_Standard.sdc_Flags,
  389.                         edc->edc_ExecType, edc->edc_Priority, edc->edc_Stack))
  390.  
  391.     /* Set new name and ID */
  392.     SetAttrs(obj, TMA_Name, spname->sp_Data,
  393.                   TMA_ID,   edc->edc_Standard.sdc_ID,
  394.                   TAG_DONE);
  395.  
  396.     /* Copy values from data chunk */
  397.     ecd->ecd_Flags    = edc->edc_Standard.sdc_Flags & DATA_EXECF_MASK;
  398.     ecd->ecd_ExecType = edc->edc_ExecType;
  399.     ecd->ecd_Stack    = edc->edc_Stack;
  400.     ecd->ecd_Priority = edc->edc_Priority;
  401.  
  402.     /* Sanity checks */
  403.     if (ecd->ecd_ExecType > TMET_Network) ecd->ecd_ExecType = TMET_Network;
  404.     if (ecd->ecd_Priority < -128)         ecd->ecd_Priority = -128;
  405.     if (ecd->ecd_Priority >  127)         ecd->ecd_Priority =  127;
  406.     if (ecd->ecd_Stack    == 0)           ecd->ecd_Stack    = 4096;
  407.  
  408.     /* Get string values */
  409.     ecd->ecd_Command   = ReadStringProperty(tmppi->tmppi_IFFHandle, ID_TMEX,
  410.                                             ID_CMND);
  411.     ecd->ecd_HotKey    = ReadStringProperty(tmppi->tmppi_IFFHandle, ID_TMEX,
  412.                                             ID_HKEY);
  413.     ecd->ecd_Directory = ReadStringProperty(tmppi->tmppi_IFFHandle, ID_TMEX,
  414.                                             ID_CDIR);
  415.     ecd->ecd_Path      = ReadStringProperty(tmppi->tmppi_IFFHandle, ID_TMEX,
  416.                                             ID_PATH);
  417.     ecd->ecd_Output    = ReadStringProperty(tmppi->tmppi_IFFHandle, ID_TMEX,
  418.                                             ID_OUTP);
  419.     ecd->ecd_PubScreen = ReadStringProperty(tmppi->tmppi_IFFHandle, ID_TMEX,
  420.                                             ID_PSCR);
  421.  
  422.     /* All OK */
  423.     rc = TRUE;
  424.    }
  425.   }
  426.  }
  427.  
  428.  EXEC_LOG(LOG1(Result, "%ld", rc))
  429.  
  430.  return(rc);
  431. }
  432.  
  433. /* Exec class method: TMM_WriteIFF */
  434. #undef  DEBUGFUNCTION
  435. #define DEBUGFUNCTION ExecClassWriteIFF
  436. static ULONG ExecClassWriteIFF(Class *cl, Object *obj,
  437.                                struct TMP_WriteIFF *tmpwi)
  438. {
  439.  struct ExecClassData *ecd  = TYPED_INST_DATA(cl, obj);
  440.  struct ExecDATAChunk  edc;
  441.  ULONG                 mask = NotValidMasks[ecd->ecd_ExecType];
  442.  BOOL                  rc;
  443.  
  444.  EXEC_LOG(LOG1(IFFHandle, "0x%08lx", tmpwi->tmpwi_IFFHandle))
  445.  
  446.  /* Initialize DATA chunk */
  447.  edc.edc_Standard.sdc_ID    = (ULONG) obj;      /* Use objects address as ID */
  448.  edc.edc_Standard.sdc_Flags = ecd->ecd_Flags;
  449.  edc.edc_ExecType           = ecd->ecd_ExecType;
  450.  edc.edc_Stack              = ecd->ecd_Stack;
  451.  edc.edc_Priority           = ecd->ecd_Priority;
  452.  
  453.  /* Check validity of argument flag */
  454.  if (mask & VALIDF_ARGUMENTS)
  455.   edc.edc_Standard.sdc_Flags &= ~(DATA_EXECF_ARGUMENTS);
  456.  
  457.  /* a) Forward message to SuperClass first */
  458.  /* b) Push DATA chunk                     */
  459.  /* c) Push FILE chunk                     */
  460.  rc = DoSuperMethodA(cl, obj, (Msg) tmpwi)                                   &&
  461.       WriteProperty(tmpwi->tmpwi_IFFHandle, ID_DATA, &edc,
  462.                     sizeof(struct ExecDATAChunk))                            &&
  463.       WriteStringProperty(tmpwi->tmpwi_IFFHandle, ID_CMND, ecd->ecd_Command) &&
  464.       WriteStringProperty(tmpwi->tmpwi_IFFHandle, ID_HKEY, ecd->ecd_HotKey)  &&
  465.       ((mask & VALIDF_DIRECTORY) ||
  466.        WriteStringProperty(tmpwi->tmpwi_IFFHandle, ID_CDIR,
  467.                            ecd->ecd_Directory))                              &&
  468.       ((mask & VALIDF_PATH) ||
  469.        WriteStringProperty(tmpwi->tmpwi_IFFHandle, ID_PATH,
  470.                            ecd->ecd_Path))                                   &&
  471.       ((mask & VALIDF_OUTPUT) ||
  472.        WriteStringProperty(tmpwi->tmpwi_IFFHandle, ID_OUTP,
  473.                            ecd->ecd_Output))                                 &&
  474.       (((ecd->ecd_Flags & DATA_EXECF_TOFRONT) == 0) ||
  475.        WriteStringProperty(tmpwi->tmpwi_IFFHandle, ID_PSCR,
  476.                            ecd->ecd_PubScreen));
  477.  
  478.  EXEC_LOG(LOG1(Result, "%ld", rc))
  479.  
  480.  return(rc);
  481. }
  482.  
  483. /* Exec class method: TMM_WBArg */
  484. #undef  DEBUGFUNCTION
  485. #define DEBUGFUNCTION ExecClassWBArg
  486. static ULONG ExecClassWBArg(Class *cl, Object *obj, struct TMP_WBArg *tmpwa)
  487. {
  488.  ULONG rc;
  489.  
  490.  EXEC_LOG(LOG1(WBArg, "0x%08lx", tmpwa->tmpwa_Argument))
  491.  
  492.  /* First forward method to SuperClass */
  493.  if (rc = DoSuperMethodA(cl, obj, (Msg) tmpwa)) {
  494.   struct ExecClassData *ecd = TYPED_INST_DATA(cl, obj);
  495.   struct WBArg         *wa  = tmpwa->tmpwa_Argument;
  496.  
  497.   EXEC_LOG(LOG0(Set gadget contents))
  498.  
  499.   /* Yes, set gadget contents */
  500.   SetAttrs(ecd->ecd_TypeCycle, MUIA_Cycle_Active,    TMET_WB,     TAG_DONE);
  501.   SetAttrs(ecd->ecd_CmdString, MUIA_String_Contents, wa->wa_Name, TAG_DONE);
  502.  
  503.   /* Get stack size from icon */
  504.   {
  505.    struct DiskObject *dobj;
  506.    BPTR               oldcd;
  507.  
  508.    /* Go to icon directory */
  509.    oldcd = CurrentDir(wa->wa_Lock);
  510.  
  511.    /* Load icon */
  512.    if (dobj = GetDiskObject(wa->wa_Name)) {
  513.  
  514.     EXEC_LOG(LOG1(DiskObject, "0x%08lx", dobj))
  515.  
  516.     /* Tool icon? */
  517.     if (dobj->do_Type == WBTOOL) {
  518.  
  519.      EXEC_LOG(LOG1(Stack size, "%ld", dobj->do_StackSize))
  520.  
  521.      /* Yes, get stack size from icon */
  522.      SetAttrs(ecd->ecd_StackInteger, MUIA_String_Integer, dobj->do_StackSize,
  523.                                      TAG_DONE);
  524.     }
  525.  
  526.     /* Free icon */
  527.     FreeDiskObject(dobj);
  528.    }
  529.  
  530.    /* Go back to old directory */
  531.    CurrentDir(oldcd);
  532.   }
  533.  
  534.   /* Get current directory name */
  535.   {
  536.    char *dir;
  537.  
  538.    /* Allocate memory for buffer */
  539.    if (dir = GetMemory(LENGTH_FILENAME)) {
  540.  
  541.     EXEC_LOG(LOG1(Buffer, "0x%08lx", dir))
  542.  
  543.     /* Create name from lock */
  544.     if (NameFromLock(wa->wa_Lock, dir, LENGTH_FILENAME)) {
  545.  
  546.      EXEC_LOG(LOG1(Directory, "%s", dir))
  547.  
  548.      /* Set directory gadget contents */
  549.      SetAttrs(ecd->ecd_DirString, MUIA_String_Contents, dir, TAG_DONE);
  550.     }
  551.  
  552.     /* Free buffer */
  553.     FreeMemory(dir, LENGTH_FILENAME);
  554.    }
  555.   }
  556.  }
  557.  
  558.  EXEC_LOG(LOG1(Result, "0x%08lx", rc))
  559.  
  560.  return(rc);
  561. }
  562.  
  563. /* Exec class method dispatcher */
  564. #undef  DEBUGFUNCTION
  565. #define DEBUGFUNCTION ExecClassDispatcher
  566. __geta4 static ULONG ExecClassDispatcher(__a0 Class *cl, __a2 Object *obj,
  567.                                          __a1 Msg msg)
  568. {
  569.  ULONG rc;
  570.  
  571.  EXEC_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  572.                cl, obj, msg))
  573.  
  574.  switch(msg->MethodID) {
  575.   /* BOOPSI methods */
  576.   case OM_NEW:
  577.    rc = ExecClassNew(cl, obj, (struct opSet *) msg);
  578.    break;
  579.  
  580.   case OM_DISPOSE:
  581.    rc = ExecClassDispose(cl, obj, msg);
  582.    break;
  583.  
  584.   /* TM methods */
  585.   case TMM_Finish:
  586.    rc = ExecClassFinish(cl, obj, (struct TMP_Finish *) msg);
  587.    break;
  588.  
  589.   case TMM_Edit:
  590.    rc = ExecClassEdit(cl, obj, (struct TMP_Edit *) msg);
  591.    break;
  592.  
  593.   case TMM_Change:
  594.    rc = ExecClassChange(cl, obj);
  595.    break;
  596.  
  597.   case TMM_ParseIFF:
  598.    rc = ExecClassParseIFF(cl, obj, (struct TMP_ParseIFF *) msg);
  599.    break;
  600.  
  601.   case TMM_WriteIFF:
  602.    rc = ExecClassWriteIFF(cl, obj, (struct TMP_WriteIFF *) msg);
  603.    break;
  604.  
  605.   case TMM_WBArg:
  606.    rc = ExecClassWBArg(cl, obj, (struct TMP_WBArg *) msg);
  607.    break;
  608.  
  609.   /* Unknown method -> delegate to SuperClass */
  610.   default:
  611.    rc = DoSuperMethodA(cl, obj, msg);
  612.    break;
  613.  }
  614.  
  615.  return(rc);
  616. }
  617.  
  618. /* Create Exec class */
  619. #undef  DEBUGFUNCTION
  620. #define DEBUGFUNCTION CreateExecClass
  621. struct MUI_CustomClass *CreateExecClass(void)
  622. {
  623.  struct MUI_CustomClass *rc;
  624.  
  625.  /* Create class */
  626.  if (rc = MUI_CreateCustomClass(NULL, NULL, BaseClass,
  627.                                 sizeof(struct ExecClassData),
  628.                                 ExecClassDispatcher)) {
  629.  
  630.   /* Localize strings */
  631.   TextTitle                       = TranslateString(
  632.                                         LOCALE_TEXT_EXEC_TITLE_STR,
  633.                                         LOCALE_TEXT_EXEC_TITLE);
  634.   HelpCommand                     = TranslateString(
  635.                                         LOCALE_HELP_EXEC_COMMAND_STR,
  636.                                         LOCALE_HELP_EXEC_COMMAND);
  637.   TextExecType                    = TranslateString(
  638.                                         LOCALE_TEXT_EXEC_TYPE_STR,
  639.                                         LOCALE_TEXT_EXEC_TYPE);
  640.   HelpExecType                    = TranslateString(
  641.                                         LOCALE_HELP_EXEC_TYPE_STR,
  642.                                         LOCALE_HELP_EXEC_TYPE);
  643.   TextExecTypes[TMET_CLI]         = TranslateString(
  644.                                         LOCALE_TEXT_EXEC_TYPE_SHELL_STR,
  645.                                         LOCALE_TEXT_EXEC_TYPE_SHELL);
  646.   TextExecTypes[TMET_WB]          = TranslateString(
  647.                                         LOCALE_TEXT_EXEC_TYPE_WORKBENCH_STR,
  648.                                         LOCALE_TEXT_EXEC_TYPE_WORKBENCH);
  649.   TextExecTypes[TMET_ARexx]       = TranslateString(
  650.                                         LOCALE_TEXT_EXEC_TYPE_AREXX_STR,
  651.                                         LOCALE_TEXT_EXEC_TYPE_AREXX);
  652.   TextExecTypes[TMET_Dock]        = TextGlobalDock;
  653.   TextExecTypes[TMET_HotKey]      = TextGlobalHotKey;
  654.   TextExecTypes[TMET_Network]     = TranslateString(
  655.                                         LOCALE_TEXT_EXEC_TYPE_NETWORK_STR,
  656.                                         LOCALE_TEXT_EXEC_TYPE_NETWORK);
  657.   TextExecTypes[TMET_Network + 1] = NULL;
  658.   HelpHotKey                      = TranslateString(
  659.                                         LOCALE_HELP_EXEC_HOTKEY_STR,
  660.                                         LOCALE_HELP_EXEC_HOTKEY);
  661.   TextStack                       = TranslateString(
  662.                                         LOCALE_TEXT_EXEC_STACK_STR,
  663.                                         LOCALE_TEXT_EXEC_STACK);
  664.   HelpStack                       = TranslateString(
  665.                                         LOCALE_HELP_EXEC_STACK_STR,
  666.                                         LOCALE_HELP_EXEC_STACK);
  667.   TextPriority                    = TranslateString(
  668.                                         LOCALE_TEXT_EXEC_PRIORITY_STR,
  669.                                         LOCALE_TEXT_EXEC_PRIORITY);
  670.   HelpPriority                    = TranslateString(
  671.                                         LOCALE_HELP_EXEC_PRIORITY_STR,
  672.                                         LOCALE_HELP_EXEC_PRIORITY);
  673.   HelpDirectory                   = TranslateString(
  674.                                         LOCALE_HELP_EXEC_DIRECTORY_STR,
  675.                                         LOCALE_HELP_EXEC_DIRECTORY);
  676.   TextPath                        = TranslateString(
  677.                                         LOCALE_TEXT_EXEC_PATH_STR,
  678.                                         LOCALE_TEXT_EXEC_PATH);
  679.   HelpPath                        = TranslateString(
  680.                                         LOCALE_HELP_EXEC_PATH_STR,
  681.                                         LOCALE_HELP_EXEC_PATH);
  682.   TextOutput                      = TranslateString(
  683.                                         LOCALE_TEXT_EXEC_OUTPUT_FILE_STR,
  684.                                         LOCALE_TEXT_EXEC_OUTPUT_FILE);
  685.   HelpOutput                      = TranslateString(
  686.                                         LOCALE_HELP_EXEC_OUTPUT_FILE_STR,
  687.                                         LOCALE_HELP_EXEC_OUTPUT_FILE);
  688.   HelpPublicScreen                = TranslateString(
  689.                                         LOCALE_HELP_EXEC_PUBLIC_SCREEN_STR,
  690.                                         LOCALE_HELP_EXEC_PUBLIC_SCREEN);
  691.   TextArguments                   = TranslateString(
  692.                                         LOCALE_TEXT_EXEC_ARGUMENTS_STR,
  693.                                         LOCALE_TEXT_EXEC_ARGUMENTS);
  694.   HelpArguments                   = TranslateString(
  695.                                         LOCALE_HELP_EXEC_ARGUMENTS_STR,
  696.                                         LOCALE_HELP_EXEC_ARGUMENTS);
  697.   TextToFront                     = TranslateString(
  698.                                         LOCALE_TEXT_EXEC_TO_FRONT_STR,
  699.                                         LOCALE_TEXT_EXEC_TO_FRONT);
  700.   HelpToFront                     = TranslateString(
  701.                                         LOCALE_HELP_EXEC_TO_FRONT_STR,
  702.                                         LOCALE_HELP_EXEC_TO_FRONT);
  703.  }
  704.  
  705.  EXEC_LOG(LOG1(Result, "0x%08lx", rc))
  706.  
  707.  return(rc);
  708. }
  709.